from pydub import AudioSegment  # 音频处理库
import json
import os
import shutil
import pyttsx3  # 文本转语音引擎
from typing import List, Dict  # 类型注解

class TTSService:
    def __init__(self):
        """初始化TTS引擎和语音参数"""
        self.engine = pyttsx3.init()  # 初始化TTS引擎
        
        # 设置语音参数
        self.engine.setProperty('rate', 150)  # 设置语速(默认200)
        self.engine.setProperty('volume', 0.9)  # 设置音量(0-1)
        
        # 获取并设置系统默认语音
        voices = self.engine.getProperty('voices')
        if len(voices) > 0:
            self.engine.setProperty('voice', voices[0].id)  # 使用第一个可用语音

    def text_to_speech(self, script_content: Dict, output_dir: str) -> List[Dict]:
        """
        主方法：将文本脚本转换为语音文件
        :param script_content: 包含segments的字典，每个segment有content和duration
        :param output_dir: 输出目录路径
        :return: 返回时间线信息列表，包含每个segment的开始/结束时间和内容
        """
        # 输入验证
        if not script_content or 'segments' not in script_content:
            raise ValueError("无效的脚本内容，缺少segments字段")
            
        segments = script_content['segments']  # 获取segments列表
        timeline = []  # 存储时间线信息
        current_time = 0.0  # 当前时间指针
        full_script=''
        total_time=0.0
    

        try:
            # 确保输出目录存在
            os.makedirs(output_dir, exist_ok=True)
            # 处理每个segment
            for idx, segment in enumerate(segments):
                # 验证segment格式
                if 'content' not in segment or 'duration' not in segment:
                    raise ValueError(f"第{idx}个segment缺少content或duration字段")
                
                # 拼接内容（检查字段是否存在）
                segment_text = ''
                if 'content' in segment:
                    segment_text += segment['content']
                if 'visual_cue' in segment:
                    segment_text += segment['visual_cue']
                if 'transition' in segment:
                    segment_text += segment['transition']
                
                full_script += segment_text
                total_time+=segment['duration']

                # 记录时间信息
                timeline.append({
                    'start': round(current_time, 2),  # 开始时间
                    'end': round(current_time + segment['duration'], 2),  # 结束时间
                })
                

            # 使用full_script生成完整的音频文件
            output_file = os.path.join(output_dir, 'full_audio.mp3')  # 完整音频文件路径
            self.engine.save_to_file(full_script, output_file)  # 保存音频文件
            self.engine.runAndWait()  # 等待音频文件生成完成
            # 使用total_time调整完整音频文件的时长
            self._adjust_audio_duration(output_file, total_time)
            
            return timeline  # 返回时间线信息
            
        except Exception as e:
            raise RuntimeError(f"语音生成失败: {str(e)}")
        
    def _adjust_audio_duration(self, file_path: str, target_duration: float):
        """
        调整音频文件到指定时长
        :param file_path: 音频文件路径
        :param target_duration: 目标时长(秒)
        """
        """调整音频文件到指定时长"""
        try:
            audio = AudioSegment.from_file(file_path)
            current_duration = len(audio) / 1000
            
            if current_duration < target_duration:
                silence = AudioSegment.silent(duration=int((target_duration - current_duration) * 1000))
                audio += silence
            elif current_duration > target_duration:
                audio = audio[:int(target_duration * 1000)]
                
            audio.export(file_path, format="mp3")
        except Exception as e:
            raise RuntimeError(f"调整音频时长失败: {str(e)}")